<!--created by yuyupeng-->
<!--2023/11/23-->
<!-- 业务实体详细字段表格 -->
<template>
  <div>
    <a-row v-if="showOperationBt">
      <a-col :span="12">
        <a-input
          v-model="searchValue"
          :style="{ width: '320px' }"
          placeholder="请输入要搜索的备注或字段名或属性名"
          size="small"
          allow-clear
          @input="searchInputChange"
        >
          <template #suffix>
            <icon-search />
          </template>
        </a-input>
      </a-col>
      <a-col :span="12">
        <a-row justify="end">
          <a-space style="margin-bottom: 7px">
            <Button.ButtonGroup size="small">
              <!-- 添加按钮暂时不放开，以为所属表名不好写，目前只支持从库表映射中加字段 -->
              <a-tooltip v-if="false" content="添加">
                <a-button @click="addField">
                  <template #icon>
                    <icon-plus />
                  </template>
                </a-button>
              </a-tooltip>
              <a-tooltip content="删除">
                <a-button
                  :disabled="selectedFields.length === 0"
                  @click="removeField"
                >
                  <template #icon>
                    <icon-delete />
                  </template>
                </a-button>
              </a-tooltip>
              <a-tooltip content="上移">
                <a-button
                  :disabled="selectedFields.length !== 1 || filterFlag"
                  @click="clickUp()"
                >
                  <template #icon>
                    <icon-caret-up />
                  </template>
                </a-button>
              </a-tooltip>
              <a-tooltip content="下移">
                <a-button
                  :disabled="selectedFields.length !== 1 || filterFlag"
                  @click="clickDown()"
                >
                  <template #icon>
                    <icon-caret-down />
                  </template>
                </a-button>
              </a-tooltip>
            </Button.ButtonGroup>
          </a-space>
        </a-row>
      </a-col>
    </a-row>

    <!--表格：表字段-->
    <a-table
      v-model:selected-keys="selectedFields"
      :columns="COLUMNS_FIELD"
      :data="fieldList"
      :scroll="{ y: 400 }"
      row-key="id"
      :row-selection="showRowSelection ? rowSelection : undefined"
      :pagination="false"
    >
      <!--插槽：所属表名-->
      <template #tableName="{ record }">
        <a-tag
          v-if="selectedTableNameList.length > 0"
          :color="tagColorList[selectedTableNameList.indexOf(record.tableName)]"
          >{{ record.tableName }}</a-tag
        >
      </template>
      <!--插槽（通用）：多选框-->
      <template #checkBox="{ rowIndex, column }">
        <a-checkbox
          v-model="fieldList[rowIndex][column.dataIndex]"
          :disabled="fieldList[rowIndex].disabled"
        />
      </template>

      <!--插槽（通用）：普通输入框-->
      <template #inputBox="{ rowIndex, column }">
        <a-input
          v-model="fieldList[rowIndex][column.dataIndex]"
          :disabled="fieldList[rowIndex].disabled"
        />
      </template>

      <!--插槽（通用）：数字输入框-->
      <template #numberBox="{ rowIndex, column }">
        <a-input-number
          v-model="fieldList[rowIndex][column.dataIndex]"
          :disabled="fieldList[rowIndex].disabled"
        />
      </template>

      <!--插槽：字段类型-->
      <template #columnType="{ rowIndex }">
        <a-select
          v-model="fieldList[rowIndex].columnType"
          :disabled="fieldList[rowIndex].disabled"
          :options="columnTypeOptions"
        />
      </template>
    </a-table>
  </div>
</template>

<script setup lang="ts">
  import { ref, reactive, computed, defineExpose, watch, toRefs } from 'vue';
  import {
    TableColumnData,
    TableRowSelection,
    Button,
  } from '@arco-design/web-vue';

  const props = defineProps({
    showRowSelection: { type: Boolean, default: true }, // 控制是否展示勾选框
    showOperationBt: { type: Boolean, default: true }, // 控制是否展示顶部操作按钮
  });

  const {
    showRowSelection, // 控制是否展示勾选框
    showOperationBt, // 控制是否展示顶部操作按钮
  } = toRefs(props); // 根据props创建多个 ref 对象

  // 逻辑删除标志，为true时有字段
  // const hasDelete = ref<boolean>(false);
  // const hasVersion = ref<boolean>(false);

  const rowSelection = reactive<TableRowSelection>({
    type: 'checkbox',
    showCheckedAll: true,
    onlyCurrent: false,
  });
  const columnTypeOptions = [
    { label: 'STRING', value: 'STRING' },
    { label: 'LONG', value: 'LONG' },
    { label: 'DATE', value: 'DATE' },
    { label: 'BOOLEAN', value: 'BOOLEAN' },
    { label: 'INTEGER', value: 'INTEGER' },
  ];
  const selectedFields = ref<string[]>([]);
  const selectedTableNameList = ref<string[]>([]); // 用于记录当前选择了几张表
  const tagColorList = ['orangered', 'green', 'blue', 'magenta']; // 标签颜色数组
  const filterFlag = ref<boolean>(false);
  const searchValue = ref<string>('');
  const fieldList = computed(() => {
    // return [...editablefieldList.value, ...disabledfieldList.value];
    if (filterFlag.value) {
      // 要筛选一下
      const filterList = [] as any[];
      editablefieldList.value.forEach((item) => {
        if (
          item.jsonName.indexOf(searchValue.value) > -1 ||
          item.fieldName.indexOf(searchValue.value) > -1 ||
          item.comment.indexOf(searchValue.value) > -1
        ) {
          filterList.push(item);
        }
      });
      return filterList;
    }
    return [...editablefieldList.value];
  });
  // 可编辑的字段
  const editablefieldList = ref<any[]>([]);
  // 不可编辑的字段：delete和version
  /* const disabledfieldList = computed(() => {
    const list = [];
    if (hasDelete.value) {
      list.push({
        id: Math.random().toString(16).slice(2),
        fieldName: 'deleted',
        jsonName: '是否删除',
        columnType: columnTypes.bit,
        nullable: false,
        primaryKey: false,
        autoIncrement: false,
        disabled: true,
      });
    }
    if (hasVersion.value) {
      list.push({
        id: Math.random().toString(16).slice(2),
        fieldName: 'version',
        jsonName: '乐观锁',
        columnType: DataTypes.int,
        nullable: false,
        primaryKey: false,
        autoIncrement: false,
        disabled: true,
      });
    }
    return list;
  }); */
  const COLUMNS_FIELD: TableColumnData[] = [
    {
      title: '序号',
      dataIndex: 'index',
      width: 60,
      fixed: 'left',
      render: ({ rowIndex }) => rowIndex + 1,
    },
    {
      title: '数据源',
      dataIndex: 'dataSourceName',
      width: 150,
    },
    {
      title: '所属表名',
      dataIndex: 'tableName',
      width: 150,
      slotName: 'tableName',
    },
    {
      title: '数据库字段列名',
      dataIndex: 'fieldName',
      width: 150,
    },
    {
      title: 'Json属性',
      dataIndex: 'jsonName',
      width: 150,
      slotName: 'inputBox',
    },
    {
      title: 'Json类型',
      dataIndex: 'columnType',
      width: 100,
    },
    {
      title: '备注',
      dataIndex: 'comment',
      slotName: 'inputBox',
      width: 200,
    },
    /* {
      title: '小数点',
      dataIndex: 'decimalPoint',
      slotName: 'numberBox',
      width: 150,
    },
    {
      title: '是否主键',
      dataIndex: 'primaryKey',
      width: 100,
      align: 'center',
      slotName: 'checkBox',
    }, */
  ];
  const emits = defineEmits(['tableNameListChange']);
  watch(searchValue, (val) => {
    if (val.length > 0) {
      filterFlag.value = true;
    } else {
      filterFlag.value = false;
    }
  });
  watch(fieldList, (val) => {
    selectedTableNameList.value = []; // 先清空一下
    if (val.length > 0) {
      val.forEach((item) => {
        if (selectedTableNameList.value.indexOf(item.tableName) === -1) {
          selectedTableNameList.value.push(item.tableName);
        }
      });
    }
    emits('tableNameListChange', selectedTableNameList.value);
  });
  const addField = () => {
    const newRow = {
      id: new Date().getTime(),
      fieldName: '',
      jsonName: '',
      columnType: '',
      comment: '',
      /* decimalPoint: 0,
      defaultValue: '',
      nullable: false,
      primaryKey: false,
      autoIncrement: false, */
    };
    editablefieldList.value = [...editablefieldList.value, newRow];
  };
  const removeField = () => {
    const newList = editablefieldList.value.filter(
      (elem) => !selectedFields.value.includes(elem.id)
    );
    editablefieldList.value = newList;
    selectedFields.value = [];
  };
  const getFieldList = () => {
    return fieldList.value;
  };
  const clearFieldList = () => {
    editablefieldList.value = [];
  };
  /**
   * 批量添加表格信息，库表映射的时候可以用到
   * @param tbData
   */
  const addTbDataBatch = (tbData: any[]) => {
    editablefieldList.value = editablefieldList.value.concat(tbData);
  };
  /**
   * @description 搜索输入框变化触发
   * @param value
   */
  const searchInputChange = () => {
    if (searchValue.value.length > 0) {
      filterFlag.value = true;
    } else {
      filterFlag.value = false;
    }
  };
  /**
   * @description 点击上移
   * @param index
   */
  const clickUp = () => {
    let currentIndex = 0;
    editablefieldList.value.forEach((item, index) => {
      if (item.id === selectedFields.value[0]) {
        currentIndex = index;
      }
    });
    if (currentIndex !== 0) {
      // 除了已经上移到顶的情况，其余的都可以上移
      const oldEditableFieldList = [...editablefieldList.value];
      // eslint-disable-next-line prefer-destructuring
      oldEditableFieldList[currentIndex] = oldEditableFieldList.splice(
        currentIndex - 1,
        1,
        oldEditableFieldList[currentIndex]
      )[0];
      editablefieldList.value = [...oldEditableFieldList];
    }
  };
  /**
   * @description 点击下移
   * @param index
   */
  const clickDown = () => {
    let currentIndex = 0;
    editablefieldList.value.forEach((item, index) => {
      if (item.id === selectedFields.value[0]) {
        currentIndex = index;
      }
    });
    if (currentIndex !== editablefieldList.value.length - 1) {
      // 除了已经下移到底的情况，其余的都可以下移
      const oldEditableFieldList = [...editablefieldList.value];
      // eslint-disable-next-line prefer-destructuring
      oldEditableFieldList[currentIndex] = oldEditableFieldList.splice(
        currentIndex + 1,
        1,
        oldEditableFieldList[currentIndex]
      )[0];
      editablefieldList.value = [...oldEditableFieldList];
    }
  };
  defineExpose({ getFieldList, clearFieldList, addTbDataBatch }); // 在<srcipt setup>的写法中，想要子组件中的方法可以被父组件调用，要通过defineExpose将方法暴露出去
</script>
